/*
 * Copyright (c) 2013. wyouflf (wyouflf@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.ifly.voice.app;

import java.util.List;

import android.text.TextUtils;
import android.util.Log;

/**
 * Log���ߣ�����android.util.Log�� tag�Զ������ʽ:
 * customTagPrefix:className.methodName(L:lineNumber),
 * customTagPrefixΪ��ʱֻ�����className.methodName(L:lineNumber)��
 * <p/>
 */
public class Logs
{

	public static String customTagPrefix = "LogUtils";

	private Logs()
	{
	}

	public static boolean allowD = true;
	public static boolean allowE = true;
	public static boolean allowI = true;
	public static boolean allowV = true;
	public static boolean allowW = true;
	public static boolean allowWtf = true;

	private static String generateTag(StackTraceElement caller)
	{
		String tag = "%s.%s(L:%d)";
		String callerClazzName = caller.getClassName();
		callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
		tag = String.format(tag, callerClazzName, caller.getMethodName(), caller.getLineNumber());
		tag = TextUtils.isEmpty(customTagPrefix) ? tag : customTagPrefix + ":" + tag;
		return tag;
	}

	public static CustomLogger customLogger;

	public interface CustomLogger
	{
		void d(String tag, String content);

		void d(String tag, String content, Throwable tr);

		void e(String tag, String content);

		void e(String tag, String content, Throwable tr);

		void i(String tag, String content);

		void i(String tag, String content, Throwable tr);

		void v(String tag, String content);

		void v(String tag, String content, Throwable tr);

		void w(String tag, String content);

		void w(String tag, String content, Throwable tr);

		void w(String tag, Throwable tr);

		void wtf(String tag, String content);

		void wtf(String tag, String content, Throwable tr);

		void wtf(String tag, Throwable tr);
	}

	public static void d(String content)
	{
		if (!allowD)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.d(tag, content);
		}
		else
		{
			if (content == null || content.toString().length() == 0)
			{
				content = tag;
			}
			Log.d(tag, content);
		}
	}

	public static void d(Object content)
	{
		if (!allowD)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.d(tag, content.toString());
		}
		else
		{
			if (content == null || content.toString().length() == 0)
			{
				content = tag;
			}
			if (content instanceof String[])
			{
				String[] strings = (String[]) content;

				for (int i = 0; i < strings.length; i++)
				{
					Log.d(tag, "string[" + i + "]=" + strings[i]);
				}

			}
			else if (content instanceof List<?>)
			{
				List<?> list = (List<?>) content;
				for (Object object : list)
				{
					Log.d(tag, object.toString());
				}
			}
			else
			{
				Log.d(tag, content.toString());
			}

		}
	}

	public static void d(String content, Throwable tr)
	{
		if (!allowD)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.d(tag, content, tr);
		}
		else
		{
			Log.d(tag, content, tr);
		}
	}

	public static void e(String content)
	{
		if (!allowE)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.e(tag, content);
		}
		else
		{
			Log.e(tag, content);
		}
	}

	public static void e(String content, Throwable tr)
	{
		if (!allowE)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.e(tag, content, tr);
		}
		else
		{
			Log.e(tag, content, tr);
		}
	}

	public static void i(String content)
	{
		if (!allowI)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.i(tag, content);
		}
		else
		{
			Log.i(tag, content);
		}
	}

	public static void i(String content, Throwable tr)
	{
		if (!allowI)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.i(tag, content, tr);
		}
		else
		{
			Log.i(tag, content, tr);
		}
	}

	public static void v(String content)
	{
		if (!allowV)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.v(tag, content);
		}
		else
		{
			Log.v(tag, content);
		}
	}

	public static void v(String content, Throwable tr)
	{
		if (!allowV)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.v(tag, content, tr);
		}
		else
		{
			Log.v(tag, content, tr);
		}
	}

	public static void w(String content)
	{
		if (!allowW)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.w(tag, content);
		}
		else
		{
			Log.w(tag, content);
		}
	}

	public static void w(String content, Throwable tr)
	{
		if (!allowW)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.w(tag, content, tr);
		}
		else
		{
			Log.w(tag, content, tr);
		}
	}

	public static void w(Throwable tr)
	{
		if (!allowW)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.w(tag, tr);
		}
		else
		{
			Log.w(tag, tr);
		}
	}

	public static void wtf(String content)
	{
		if (!allowWtf)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.wtf(tag, content);
		}
		else
		{
			Log.wtf(tag, content);
		}
	}

	public static void wtf(String content, Throwable tr)
	{
		if (!allowWtf)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.wtf(tag, content, tr);
		}
		else
		{
			Log.wtf(tag, content, tr);
		}
	}

	public static void wtf(Throwable tr)
	{
		if (!allowWtf)
			return;
		StackTraceElement caller = getCallerStackTraceElement();
		String tag = generateTag(caller);

		if (customLogger != null)
		{
			customLogger.wtf(tag, tr);
		}
		else
		{
			Log.wtf(tag, tr);
		}
	}

	public static StackTraceElement getCallerStackTraceElement()
	{
		StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
		return stackTrace[4];
	}

}